<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2017/12/6
 * Time: 15:02
 */

namespace common\business\qywx;

use common\business\QywxHelper;
use common\consts\CommonResources;
use common\helpers\StringUtil;
use common\models\Log;
use Yii;
use common\models\qywx\QywxUser;
use common\result\ActionResult;
use yii\helpers\Json;

class QywxUserApiHandler extends QywxApiHandler
{
    /**
     * @param $userid
     * @param $name
     * @param $department array
     * @param $position
     * @param $mobile
     * @param $gender
     * @param $email
     * @param $avatar
     * @param $status integer
     * @param $isleader integer
     * @param $extattr
     * @param $english_name
     * @param $telephone
     * @param $enable
     * @param $hide_mobile
     * @param $order array
     * @return QywxUser
     */
    protected function apiResponseToQywxUser($userid, $name, $department, $position, $mobile,
                                             $gender, $email, $avatar, $status, $isleader, $extattr,
                                             $english_name, $telephone, $enable, $hide_mobile, $order){
        return new QywxUser([
            'userid' => $userid,
            'name' => $name,
            'department' => strval($department[0]),
            'position' => $position,
            'mobile' => $mobile,
            'gender' => $gender,
            'email' => $email,
            'avatar' => $avatar,
            'status' => $status,
            'is_leader' => $isleader,
            'extattr' => Json::encode($extattr),
            'english_name' => $english_name,
            'telephone' => $telephone,
            'order' => strval($order[0]),
        ]);
    }

    /**
     * @param $response string
     * @return QywxUser
     */
    protected function apiResponseStrToQywxUser($response){
        $userArr = Json::decode($response);

        return new QywxUser([
            'userid' => $userArr['userid'],
            'name' => $userArr['name'],
            'department' => strval($userArr['department'][0]),
            'position' => $userArr['position'],
            'mobile' => $userArr['mobile'],
            'gender' => $userArr['gender'],
            'email' => $userArr['email'],
            'avatar' => $userArr['avatar'],
            'status' => $userArr['status'],
            'is_leader' => $userArr['isleader'],
            'extattr' => Json::encode($userArr['extattr']),
            'english_name' => $userArr['english_name'],
            'telephone' => $userArr['telephone'],
            'order' => strval($userArr['order'][0]),
        ]);
    }


    /**
     * @param $user_id string
     * @return null|QywxUser
     */
    public function findOne($user_id){
        $returnValue = null;
        $getWriteBackHandler = function(
            $errcode, $errmsg, $userid = null, $name = null, $department = null, $position = null, $mobile = null,
            $gender = null, $email = null, $avatar = null, $status = null, $isleader = null, $extattr = null,
            $english_name = null, $telephone = null, $enable = null, $hide_mobile = null, $order = null) use (&$returnValue, $user_id) {
            if (intval($errcode) == 0) {
                $newObj = $this->apiResponseToQywxUser($userid, $name, $department, $position, $mobile,
                    $gender, $email, $avatar, $status, $isleader, $extattr,
                    $english_name, $telephone, $enable, $hide_mobile, $order);

                $objInDb = QywxUser::findOne([
                    'userid' => $userid,
                ]);
                if ($objInDb){
                    $updateResult =  $this->update($newObj, $objInDb, [
                        'userid',
                        'name',
//                        'number',
                        'mobile',
                        'department',
//                        'order',
                        'position',
                        'gender',
                        'email',
                        'is_leader',
                        'avatar',
                        'telephone',
                        'english_name',
//                        'extattr',
//                        'status',
//                        'memo',
                    ]);
                    if ($updateResult->isSuccess){
                        $returnValue = $newObj;
                    }
                    else {
                        $returnValue = null;
                    }
                }
                else {
                    $createResult = $this->create($newObj);
                    if ($createResult->isSuccess){
                        $returnValue = $newObj;
                    }
                }
            }
            else {
                $objInDb = QywxUser::findOne([
                    'userid' => $user_id,
                ]);
                if ($objInDb){
                    $this->delete($objInDb);
                }
                $returnValue = null;
            }
        };

        $this->getOnQywx($user_id, $getWriteBackHandler);
        return $returnValue;
    }

    /**
     * @param $userid string
     * @param null $writeBackHandler
     * @param bool $asArray
     * @return bool
     */
    public function getOnQywx($userid, $writeBackHandler = null, $asArray = false){
        $url = $this->baseUrl . '/user/get';
        $params = [
            'access_token' => QywxHelper::getAccessTokenVal(),
            'userid' => $userid,
        ];
        return $this->getJson($url, $params, $writeBackHandler, $asArray);
    }
    /**
     * @param $jsonArr
    {
    "userid": "zhangsan",
    "name": "张三",
    "english_name": "jackzhang",
    "mobile": "15913215421",
    "department": [1, 2],
    "order":[10,40],
    "position": "产品经理",
    "gender": "1",
    "email": "zhangsan@gzdev.com",
    "isleader": 1,
    "enable":1,
    "avatar_mediaid": "2-G6nrLmr5EC3MNb_-zL1dDdzkd0p7cNliYu9V5w7o8K0",
    "telephone": "020-123456"，
    "extattr": {"attrs":[{"name":"爱好","value":"旅游"},{"name":"卡号","value":"1234567234"}]}
    }
     * @param callback|null $writeBackHandler
     * @param bool $asArray
     * @return bool
     */
    public function createOnQywx($jsonStr, $writeBackHandler = null, $asArray = false){
        $url = $this->baseUrl . '/user/create';
        $params = [
            'access_token' => QywxHelper::getAccessTokenVal(),
        ];
        return $this->postJson($url, $params, $jsonStr, $writeBackHandler, $asArray);
    }

    /**
     * @param $jsonArr
    {
    "userid": "zhangsan",
    "name": "李四",
    "department": [1],
    "order": [10],
    "position": "后台工程师",
    "mobile": "15913215421",
    "gender": "1",
    "email": "zhangsan@gzdev.com",
    "isleader": 0,
    "enable": 1,
    "avatar_mediaid": "2-G6nrLmr5EC3MNb_-zL1dDdzkd0p7cNliYu9V5w7o8K0",
    "telephone": "020-123456",
    "english_name": "jackzhang",
    "extattr": {"attrs":[{"name":"爱好","value":"旅游"},{"name":"卡号","value":"1234567234"}]}
    }
     * @param callback|null $writeBackHandler
     * @param bool $asArray
     * @return bool
     */
    public function updateOnQywx($jsonStr, $writeBackHandler = null, $asArray = false){
        $url = $this->baseUrl . '/user/update';
        $params = [
            'access_token' => QywxHelper::getAccessTokenVal(),
        ];
        return $this->postJson($url, $params, $jsonStr, $writeBackHandler, $asArray);
    }

    /**
     * 根据code得到UserId
     * https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=ACCESS_TOKEN&code=CODE
     * @param $code
    {
    "errcode": 0,
    "errmsg": "ok",
    "UserId":"USERID",
    }
     * @param callback|null $writeBackHandler
     * @return bool
     */
    public function getInfoByCodeOnQywx($code, $writeBackHandler = null){
        $url = $this->baseUrl . '/user/getuserinfo';
        $params = [
            'access_token' => QywxHelper::getAccessTokenVal(),
            'code' => $code,
        ];
        return $this->getJson($url, $params, $writeBackHandler, true);
    }


    public function getInfoByUserIdOnQywx($userid){
        $returnValue = null;
        $getWriteBackHandler = function ($response) use (&$returnValue){
            $responseArr = Json::decode($response);
            $errcode = $responseArr['errcode'];
            $errmsg = $responseArr['errmsg'];
            if (intval($errcode) == 0){
                $returnValue = $this->apiResponseStrToQywxUser($response);
            }
            else {
                $errMsg = sprintf('{ errcode: %s, errormsg: %s }', $errcode, $errmsg);
                $this->addError('Get On Qywx', $errMsg);
                $returnValue = null;
            }
        };
        $this->getOnQywx($userid, $getWriteBackHandler, true);
        return $returnValue;
    }


    /**
     * @param $code string
     * @return null|QywxUser
     */
    public function getInfoByCode($code){
        $returnValue = null;
        $getWriteBackHandler = function($response) use ($code, &$returnValue)
        {
            $this->saveLog( new Log([
                'action' => CommonResources::ACTION_NAME_MSG('Get User Info By Code', 'Qywx User', $code),
                'memo' => $response,
            ]));
            $responseArr = Json::decode($response);
            $errcode = $responseArr['errcode'];
            $errmsg = $responseArr['errmsg'];
            if (intval($errcode) == 0){
                $userid = $responseArr['UserId'];
                $deviceId = $responseArr['DeviceId'];
                $returnValue = $this->getInfoByUserIdOnQywx($userid);
            }
            else {
                $errMsg = sprintf('{ errcode: %s, errormsg: %s }', $errcode, $errmsg);
                $this->addError('Create On Qywx', $errMsg);
                $returnValue = null;
            }
        };
        $this->getInfoByCodeOnQywx($code, $getWriteBackHandler);
        return $returnValue;
    }

    /**
     * @param $obj QywxUser
     * @return ActionResult
     */
    public function createQywxUser($obj){
        $getWriteBackHandler = function(
            $errcode, $errmsg, $userid = null, $name = null, $department = null, $position = null, $mobile = null,
            $gender = null, $email = null, $avatar = null, $status = null, $isleader = null, $extattr = null,
            $english_name = null, $telephone = null, $enable = null, $hide_mobile = null, $order = null)
        use ($obj) {
            $infoJson = Json::encode([
                'userid' => $obj->userid,
                'name' => $obj->name,
                'department' => $obj->department,
                'position' => $obj->position,
                'mobile' => $obj->mobile,
                'gender' => $obj->gender,
                'email' => $obj->email,
                'telephone' => $obj->telephone,
            ]);

            $writeBackHandler = function ($errcode, $errmsg){
                if (intval($errcode) > 0){
                    $errMsg = sprintf('{ errcode: %s, errormsg: %s }', $errcode, $errmsg);
                    $this->addError('Create On Qywx', $errMsg);
                }
            };
            if (intval($errcode) == 0){
//                如果记录存在，头像变更，则更新头像
                if (strcmp($obj->avatar, $avatar) != 0){
                    $obj->avatar = $avatar;
                }
                if (
                    (!StringUtil::isNullOrWhiteSpace($obj->name) && strcmp($obj->name, $name) != 0)
//                    department为数组，所以只看第一个
                    || (!StringUtil::isNullOrWhiteSpace($obj->department) && strcmp($obj->department, $department[0]) != 0)
                    || (!StringUtil::isNullOrWhiteSpace($obj->position) && strcmp($obj->position, $position) != 0)
                    || (!StringUtil::isNullOrWhiteSpace($obj->mobile) && strcmp($obj->mobile, $mobile) != 0)
                    || (!StringUtil::isNullOrWhiteSpace($obj->gender) && strcmp($obj->gender, $gender) != 0)
                    || (!StringUtil::isNullOrWhiteSpace($obj->email) && strcmp($obj->email, $email) != 0)
                    || (!StringUtil::isNullOrWhiteSpace($obj->telephone) && strcmp($obj->telephone, $telephone) != 0)
                ){
                    $this->updateOnQywx($infoJson, $writeBackHandler);
                }
            }
            else {
                $this->createOnQywx($infoJson, $writeBackHandler);
            }
        };

        $getSuccess = $this->getOnQywx($obj->userid, $getWriteBackHandler);
        if (!$getSuccess){
            return new ActionResult(false, $this->getErrorsMessage());
        }
        return $this->create($obj);
    }

    /**
     * @param QywxUser $newObj
     * @param QywxUser $oldObj
     * @return ActionResult
     */
    public function updateQywxUser($newObj, $oldObj = null){
        if (!$oldObj){
            $oldObj = QywxUser::findOne([
                'userid' => $newObj->userid
            ]);
        }

        $getWriteBackHandler = function(
            $errcode, $errmsg, $userid = null, $name = null, $department = null, $position = null, $mobile = null,
            $gender = null, $email = null, $avatar = null, $status = null, $isleader = null, $extattr = null,
            $english_name = null, $telephone = null, $enable = null, $hide_mobile = null, $order = null)
        use ($newObj) {
            $infoJson = Json::encode([
                'userid' => $newObj->userid,
                'name' => $newObj->name,
                'department' => $newObj->department,
                'position' => $newObj->position,
                'mobile' => $newObj->mobile,
                'gender' => $newObj->gender,
                'email' => $newObj->email,
                'telephone' => $newObj->telephone,
            ]);

            $writeBackHandler = function ($errcode, $errmsg){
                if (intval($errcode) > 0){
                    $errMsg = sprintf('{ errcode: %s, errormsg: %s }', $errcode, $errmsg);
                    $this->addError('Create On Qywx', $errMsg);
                }
            };
            if (intval($errcode) == 0){
//                如果记录存在，头像变更，则更新头像
                if (strcmp($newObj->avatar, $avatar) != 0){
                    $newObj->avatar = $avatar;
                }
                if (
                    (!StringUtil::isNullOrWhiteSpace($newObj->name) && strcmp($newObj->name, $name) != 0)
//                    department为数组，所以只看第一个
                    || (!StringUtil::isNullOrWhiteSpace($newObj->department) && strcmp($newObj->department, $department[0]) != 0)
                    || (!StringUtil::isNullOrWhiteSpace($newObj->position) && strcmp($newObj->position, $position) != 0)
                    || (!StringUtil::isNullOrWhiteSpace($newObj->mobile) && strcmp($newObj->mobile, $mobile) != 0)
                    || (!StringUtil::isNullOrWhiteSpace($newObj->gender) && strcmp($newObj->gender, $gender) != 0)
                    || (!StringUtil::isNullOrWhiteSpace($newObj->email) && strcmp($newObj->email, $email) != 0)
                    || (!StringUtil::isNullOrWhiteSpace($newObj->telephone) && strcmp($newObj->telephone, $telephone) != 0)
                ){
                    $this->updateOnQywx($infoJson, $writeBackHandler);
                }
            }
            else {
                $this->createOnQywx($infoJson, $writeBackHandler);
            }
        };
        $getSuccess = $this->getOnQywx($oldObj->userid, $getWriteBackHandler);
        if (!$getSuccess){
            return new ActionResult(false, $this->getErrorsMessage());
        }

        return $this->update($newObj, $oldObj, [
            'userid',
            'name',
            'number',
            'mobile',
            'department',
            'department_name',
//            'order',
            'position',
            'gender',
//            'email',
            'is_leader',
            'avatar',
            'telephone',
            'english_name',
//            'extattr',
//            'status',
            'memo',
        ]);
    }

    /**
     * @param $obj QywxUser
     * @return ActionResult
     */
    public function deleteQywxUser($obj){
        return $this->delete($obj);
    }

    /**
     * @param $idListArr array
     * @return ActionResult
     */
    public function batchDeleteQywxUser($idListArr){
        $action = Yii::t('app' , 'Batch Delete');
        $modelClass = Yii::t('app' , 'Qywx User');
        $totalResult = new ActionResult();
        foreach ($idListArr as $id){
            $userInDb = QywxUser::findOne($id);
            if ($userInDb){
                $totalResult->addSubResult($this->delete($userInDb));
            }
            else {
                $totalResult->addSubResult(new ActionResult(false, CommonResources::ACTION_FAIL_MSG($action, $modelClass, 'Record Not Found With id: '.$id)));
            }
        }
        return $totalResult;
    }
}